package httplog

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"sync"
	"unicode"

	"gitee.com/haodreams/golib/logs"
	"gitee.com/haodreams/libs/easy"
	"gitee.com/haodreams/libs/fixedlist"
)

var l *WebWriter

func init() {
	l = new(WebWriter)
	l.FixList = fixedlist.NewFixList[string](300)
	logs.AddWriter(l)
}

// WebWriter web 日志类
type WebWriter struct {
	MaxLines int `json:"maxlines"`
	sync.RWMutex
	*fixedlist.FixList[string]
}

// Init 初始化
func (m *WebWriter) Init(config string) (err error) {
	if config == "" {
		return
	}
	err = json.Unmarshal([]byte(config), m)
	if err != nil {
		return err
	}
	if m.MaxLines < 100 {
		m.MaxLines = 100
	}
	if m.MaxLines > 1000 {
		m.MaxLines = 1000
	}
	l.SetSize(m.MaxLines)
	return
}

// Write .
func (m *WebWriter) Write(b []byte) (n int, err error) {
	//log.Println(string(b))
	m.Lock()
	defer m.Unlock()
	if l != nil {
		msg := string(b)
		m.Push(&msg)
	}
	return len(b), nil
}

// {"Name": "time","Title":"时间","Type":"string","Width":160},
// {"Name": "level","Title":"级别","Type":"string","Width":70},
// {"Name": "caller","Title":"位置","Type":"string","Width":170},
// {"Name": "message","Title":"消息","Type":"string"}
type Row struct {
	Time   string `json:"time"`
	Level  string `json:"level"`
	Caller string `json:"caller"`
	Msg    string `json:"message"`
}

// HTTPLogs http 请求日志
func HTTPLogs(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	pos := 0
	limit := 100
	s := r.FormValue("limit")
	if s != "" {
		li, err := strconv.Atoi(s)
		if err == nil {
			limit = li
		}
	}

	s = r.FormValue("page")
	if s != "" {
		st, err := strconv.Atoi(s)
		if err == nil {
			pos = (st - 1) * limit
		}
	}

	idx := 0
	// rows := make([]*string, limit)
	end := pos + limit

	count := l.Len()
	if end > count {
		end = count
	}
	l.RLock()
	rows := l.Stack(idx, end)
	l.RUnlock()

	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Write([]byte(fmt.Sprintf(`{"count":%d,"code":%d, "msg":"", "data":[`, count, 200)))

	first := true
	for i, line := range rows {
		if (*line)[0] == '{' {
			if i > 0 {
				w.Write([]byte(","))
			}
			w.Write([]byte(*line))
		} else {
			if len(*line) == 0 {
				continue
			}

			if (*line)[0] == '{' {
				if first {
					first = false
				} else {
					w.Write([]byte(","))
				}
				w.Write([]byte(*line))
			} else {
				ss := easy.FieldsFuncN(*line, unicode.IsSpace, 5)
				if len(ss) != 5 {
					continue
				}
				if first {
					first = false
				} else {
					w.Write([]byte(","))
				}
				row := new(Row)
				row.Time = ss[0] + " " + ss[1]
				row.Level = strings.TrimSuffix(ss[2], "\x1b[0m")
				if len(row.Level) > 5 {
					row.Level = row.Level[5:]
				}
				row.Caller = ss[3]
				row.Msg = ss[4]
				bs, err := json.Marshal(row)
				if err != nil {
					continue
				}
				w.Write(bs)
			}

		}
	}
	w.Write([]byte("]}"))
}
